#include "Board.h"
#include <QPainter>
#include <QPoint>
#include <math.h>
#include <iostream>
#include <QMouseEvent>

Board::Board(QWidget *parent) : QWidget(parent)
{
    for(int i=0;i < 32;i++)
    {
        _s[i].init(i);
    }
}

Board::~Board()
{

}

void Board::paintEvent(QPaintEvent *)
{
    QPainter painter(this);

    // 首先绘制10条横线

    for (int i=1;i<= 10; ++i)
    {
        painter.drawLine(QPoint(_d, i*_d), QPoint(9*_d,i*_d));
    }

    // 画9条竖线
    for (int i=1; i<=9;i++)
    {
        if (i==1 ||i==9)
        {
            painter.drawLine(QPoint(i*_d, _d), QPoint(i*_d,10*_d));
        }
        else
        {
            painter.drawLine(QPoint(i*_d, _d),QPoint(i*_d,5*_d));
            painter.drawLine(QPoint(i*_d,6*_d),QPoint(i*_d,10*_d));
        }

    }
    painter.setFont(QFont("system", _d/2));


    // 画9宫格
    painter.drawLine(QPoint(4*_d,_d), QPoint(6*_d, 3*_d));
    painter.drawLine(QPoint(6*_d,_d), QPoint(4*_d, 3*_d));

    painter.drawLine(QPoint(4*_d,8*_d), QPoint(6*_d, 10*_d));
    painter.drawLine(QPoint(4*_d,10*_d), QPoint(6*_d, 8*_d));

    // 绘制32颗棋子
    for(int i=0;i<32;i++)
    {
        drawStone(painter, i);
    }
}

void Board::drawStone(QPainter &painter, int id)
{
    // 如果该子已经被吃了，那么久不需要画出来了
    if(_s[id]._dead) return;
    QPoint c=center(id);
    QRect rect=QRect(c.x()-_d/2, c.y()-_d/2, _d, _d);
    // 选中的为绿色
    if (id==_selected)
    {
       painter.setBrush(QBrush(QColor(40,104,200)));
    }
    // 没有选中的
    else
    {
        painter.setBrush(QBrush(QColor(0,0,0)));
    }
    if(_s[id]._red)
    {
        painter.setPen(Qt::red);
    }
    else
    {
       painter.setPen(Qt::white);
    }


    painter.drawEllipse(c,_d/2,_d/2);
    //添加颜色
    painter.drawText(rect, _s[id].getText(),QTextOption(Qt::AlignCenter));
}
QPoint Board::center(int id)
{
    return center(_s[id]._row, _s[id]._col);
}

QPoint Board::center(int row, int col)
{
    return QPoint((col+1)*_d, (row+1)*_d);
}

void Board::mouseReleaseEvent(QMouseEvent *event)
{
    QPoint pt=event->pos();
    // 计算点到的坐标
    int x=pt.x();
    int y=pt.y();
    int xPos =round((x+0.0)/_d)-1;
    int yPos =round((y+0.0)/_d)-1;
    int _clickId=-1;

    // 在棋盘里面
    if (xPos>=0 && xPos<9 && yPos>=0 && yPos < 10)
    {
        for(int i=0;i<32;i++)
        {
            // 选择的象棋不能是已经死了的棋子
           if(xPos==_s[i]._col && yPos==_s[i]._row && !_s[i]._dead)
           {
               _clickId=i;
               break;
           }
        }
        // 第一步选中一个棋子
        if (_selected ==-1)
        {
            //
            if (isRedStep && _s[_clickId]._id <16)
            {
                _selected = _clickId;
                update();
            }
            if (!isRedStep && _s[_clickId]._id >15)
            {
                _selected = _clickId;
                update();
            }

        }
        // 第二步，该棋子怎么走
        else
        {
           // 如果是选择相同的棋子，那么就是换了另一颗棋子
            if (_clickId !=-1 && isRedStep && _s[_clickId]._id < 16)
            {
                _selected = _clickId;
                update();
                return;
            }
            if (_clickId !=-1 && !isRedStep && _s[_clickId]._id > 15)
            {
                _selected = _clickId;
                update();
                return;
            }

            // 不能走的旗直接返回
           if (!canMove(_selected, xPos, yPos))
           {
               return;
           }
            // 能够走的情况下
           if(_clickId!=-1 && _clickId !=_selected)
           {
               _s[_clickId]._dead = true;
           }
           _s[_selected]._row = yPos;
           _s[_selected]._col = xPos;

           _selected = -1;
           isRedStep=!isRedStep;
           update();
        }
        std::cout<< "yes"<< std::endl;
        std::cout<< _selected<< std::endl;
    }
    else
    {
        // 不在棋盘里面直接清除选择的
        _selected = -1;
        std::cout<<xPos<<std::endl;
        std::cout<<yPos<<std::endl;
        std::cout<< "no"<<std::endl;
        std::cout<< _selected<< std::endl;
    }
}

// 是否能够移动
// id为第一步选中的棋子
// x,y为移动到哪个地方的坐标
// killid为要吃掉的id
bool Board::canMove(int id, int x,int y)
{
   bool result= true;
   switch(_s[id]._type)
   {
       case Stone::ZHU:
        {
            result=canMoveOfZHU(id,x,y);
            return result;
        }
       case Stone::MA:
       {
            result=canMoveOfMA(id,x,y);
            return result;
       }
       case Stone::PAO:
       {
           result=canMoveOfPao(id,x,y);
           return result;
       }
       case Stone::XIANG:
       {
           return canMoveOfXIANG(id,x,y);
       }
       case Stone::SHI:
       {
           return canMoveOfSHI(id,x,y);
       }
       case Stone::JIANG:
       {
           return canMoveOfJIANG(id,x,y);
       }
       case Stone::BING:
       {
           return canMoveOfBING(id,x,y);
       }
   }
}

bool Board::canMoveOfZHU(int selectId, int xPos, int yPos)
{

    bool result = true;
    int selfX=_s[selectId]._col;
    int selfY=_s[selectId]._row;
    // 判断自己和要去的地方之间是否有棋子
    if (selfX != xPos && selfY != yPos)
    {
        result = false;
    }
    else
    {
        // x坐标相同时
        if (selfX == xPos)
        {
            int maxRow = yPos> _s[selectId]._row ? yPos: _s[selectId]._row;
            int minRow = yPos < _s[selectId]._row ? yPos: _s[selectId]._row;
            //遍历中间是否有棋子，如果有，那么为false
            for(int i=0;i<32;i++)
            {
                if (!_s[i]._dead &&  minRow <_s[i]._row &&  _s[i]._row < maxRow && _s[i]._col == xPos )
                {
                    result = false;
                    break;
                }
            }
        }
        // y坐标相同时
        if (selfY == yPos)
        {
            int maxCol = xPos> _s[selectId]._col ? xPos: _s[selectId]._col;
            int minCol = xPos < _s[selectId]._col ? xPos: _s[selectId]._col;
            //遍历中间是否有棋子，如果有，那么为false
            for(int i=0;i<32;i++)
            {
                if (!_s[i]._dead &&  minCol <_s[i]._col && maxCol > _s[i]._col && _s[i]._row == yPos)
                {
                    result = false;
                    break;

                }
            }
        }
        return result;
    }
}

bool Board::canMoveOfMA(int selectId, int xPos, int yPos)
{
    bool result = true;
    int selfX=_s[selectId]._col;
    int selfY=_s[selectId]._row;
    // 首先判断是不是 坐标相差2和1
    if ((abs(selfX-xPos)==1 &&abs(selfY-yPos) == 2) ||(abs(selfX-xPos)==2 &&abs(selfY-yPos) == 1))
    {
        if ((abs(selfX-xPos)==1 &&abs(selfY-yPos) == 2))
        {
            // 要下的旗在本颗棋子的上方，检测本颗棋子的上面是否有棋子

            int yTemp=(selfY-yPos)>0?(selfY - 1):(selfY + 1);
            for (int i = 0; i < 32; i++)
            {
                if(_s[i]._dead) continue;
                if(_s[i]._row == yTemp && _s[i]._col == selfX)
                {
                    result = false;
                    break;
                }
            }

        }
        if ((abs(selfX-xPos)==2 && abs(selfY-yPos) == 1))
        {
            // 要下的旗在本颗棋子的上方，检测本颗棋子的上面是否有棋子
            int xTemp=(selfX-xPos)>0?(selfX - 1):(selfX + 1);
            for (int i = 0; i < 32; i++)
            {
                if(_s[i]._dead) continue;
                if (_s[i]._col == xTemp && _s[i]._row == selfY)
                {
                    result = false;
                    break;
                }
            }
        }
    }
    else
    {
        result=false;
    }
    return result;

}

 bool Board::canMoveOfPao(int selectId, int xPos, int yPos)
 {
     bool result = true;
     int selfX=_s[selectId]._col;
     int selfY=_s[selectId]._row;
     if (selfX==xPos ||selfY==yPos) {
        int number=0; // 中间棋子数目
        if(selfX == xPos)
        {
            // 首先判断中间是否有棋子
            int minRow = selfY>yPos? yPos: selfY;
            int maxRow = selfY>yPos? selfY: yPos;
            for(int i=0;i<32;i++)
            {
                if (!_s[i]._dead && _s[i]._col==selfX && _s[i]._row>minRow &&_s[i]._row < maxRow)
                {
                    number++;
                }
            }
        }
        if (selfY == yPos)
        {
            int minCol = selfX>xPos? xPos: selfX;
            int maxCol = selfX>xPos? selfX: xPos;
            for(int i=0;i<32;i++)
            {
                if (!_s[i]._dead && _s[i]._row==selfY && _s[i]._col>minCol &&_s[i]._col < maxCol)
                {
                    number++;
                }
            }
        }
            // 如果中间多颗棋子，则不能走
        if (number>1)
        {
            result = false;
        }
        // 如果中间有一颗棋子，那么判断要下的位置是否有棋子
        if (number == 1)
        {
            bool hasStone = false;
            int id =-1;
            for(int i=0;i<32;i++)
            {
                if (!_s[i]._dead && _s[i]._col==xPos&& _s[i]._row==yPos)
                {
                    id = i;
                    hasStone = true;
                    break;
                }
            }
            if (hasStone)
            {
                if(_s[selectId]._red == _s[id]._red)
                {
                    result = false;
                }
            }
            else
            {
                result = false;
            }
        }
        // 如果中间没有棋子，那么需要判断要走的地方是否有棋子，如锅有，那么不能下
        if(number ==0)
        {
            for(int i=0;i<32;i++)
            {
                if (!_s[i]._dead && _s[i]._col==xPos&& _s[i]._row==yPos)
                {
                    result = false;
                    break;
                }
            }
        }
     }
     else
     {
         result = false;
     }
     return result;
 }

bool Board::canMoveOfXIANG(int selectId, int xPos, int yPos)
{
    int col = _s[selectId]._col;
    int row = _s[selectId]._row;
    int isRed = _s[selectId]._red;
    bool result = true;
    // 如果是红色的，那么yPos只能小于16
    if ((isRed && yPos >4) || (!isRed && yPos <5))
    {
        result = false;
    }
    else
    {
        // 如果不是一个田字，那么就不能走
        if(abs(xPos-col)!= 2 ||abs(yPos-row)!=2)
        {
            result = false;
        }
        else
        {
          // 是田子的时候需要判断中间是否被一颗棋子隔开
            int middleX = (col+xPos)/2;
            int middleY = (row+yPos)/2;
            for(int i=0;i<32;i++)
            {
                if(!_s[i]._dead && _s[i]._col==middleX &&_s[i]._row==middleY)
                {
                    result = false;
                }
            }
        }
    }
    return result;
}

bool Board::canMoveOfSHI(int selectId, int xPos, int yPos)
{
    int col = _s[selectId]._col;
    int row = _s[selectId]._row;
    int isRed = _s[selectId]._red;
    bool result = true;
    if (!(3<=xPos &&xPos<=5))
    {
        result =false;
    }
    if (!(isRed&& yPos>=0 &&yPos<=2) && !(!isRed &&yPos<=9&&yPos>=7))
    {
        result = false;
    }
    if (!result) return result;

    if (!(abs(col-xPos)==1 &&abs(row-yPos)==1))
    {
        result= false;
    }
    return result;
}

bool Board::canMoveOfJIANG(int selectId, int xPos, int yPos)
{
    int col = _s[selectId]._col;
    int row = _s[selectId]._row;
    int isRed = _s[selectId]._red;
    bool result = true;
    if (!(3<=xPos &&xPos<=5))
    {
        result =false;
        return result;
    }
    if (!(isRed&& yPos>=0 &&yPos<=2) && !(!isRed &&yPos<=9&&yPos>=7))
    {
        result = false;
        return result;
    }
    if (!((abs(col-xPos)+abs(row-yPos))==1))
    {
        result=false;
        return result;
    }
    // 对面蒋的位置
    int colTemp=-1;
    int rowTemp=-1;
    for(int i=0;i< 32;i++)
    {
        if(!_s[i]._dead && _s[i]._type == Stone::JIANG &&_s[i]._red !=isRed)
        {
            colTemp = _s[i]._col;
            rowTemp = _s[i]._row;
        }
    }
    // 如果目标列和对面的将在一条线上，那么判断中间是否有棋子
    if (xPos == colTemp)
    {
        bool hasStone=false;
        int minRow = rowTemp > yPos? yPos: rowTemp;
        int maxRow = rowTemp> yPos? rowTemp: yPos;
        for(int i=minRow+1;i<maxRow;i++)
        {
           for(int j=0;j<32;j++)
           {
               if(!_s[j]._dead && _s[j]._col==xPos &&_s[j]._row==i)
               {
                   hasStone = true;
                   break;
               }
           }
        }
        if(!hasStone)
        {
            result= false;
        }
    }
    return result;
}

 bool Board::canMoveOfBING(int selectId, int xPos, int yPos)
 {
    // 首先判断是否距离为1
     int col = _s[selectId]._col;
     int row = _s[selectId]._row;
     int isRed = _s[selectId]._red;
     int result = true;
     if((abs(col-xPos)+abs(row-yPos))!=1)
     {
        return false;
     }
     else
     {
        // 红棋，且过了河的
        if(isRed&&row>=5)
        {
           if((yPos-row)<0)
           {
               result = false;
           }
        }
        if (isRed && row<5)
        {
            if(abs(col-xPos)==1 || (yPos-row)<0)
            {
                result = false;
            }
        }

        if(!isRed)
        {
            if((yPos-row)>0)
            {
                result = false;
            }
            if(row>=5 && abs(col-xPos)==1)
            {
               result=false;
            }
        }
     }
     return result;

 }

